Imports cmplib01
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Class FlexMapViewCampaignBuilder
    Inherits FlexMapViewerC

    Private Structure showSingleRuleRange
        Public ShowThis As Boolean
        Public RuleRange As Int32
        Public RuleLocation As Point
    End Structure

    Private m_RuleColor(10) As Color

    Private Enum ChitSelectionResult
        NoSelection = 0
        ChitSelected = 1
        EnemySelected = 2
        ChitUnselected = 3
    End Enum

    Public Enum BattleIconSize
        NotShown = 0
        Small = 1
        Normal = 2
    End Enum

    Shadows Event DisplayClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    Shadows Event MapScroll()
    Shadows Event Rendered()
    Shadows Event UndoRequest()
    Shadows Event BackspacePressed()
    Shadows Event DisplayMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
    Shadows Event DisplayMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)

    Public Event ObjectiveSelected()
    Public Event DeploymentZoneSelected()
    Public Event ChitSelected(ByRef Chit As ChitMember)
    Public Event ReplayTurnDrawn(ByVal turn As Integer)
    Public Event ReplayEnded()

    Const c_Module As String = "FlexMapViewCampaignBuilder"
    Const c_SelectionDistance As Int16 = 16  ' this is used to select a chit

    Private ptrCurrentGameData As cmplib01.CampaignerGameData
    Private isChitSelected As Boolean = False
    Private isDeploymentZoneSelected As Boolean = False
    Private SelectedPlayerFaction As cmplib01.Faction     ' used to draw the correct stuff. Yeah.
    Private showRule As showSingleRuleRange      ' used if the user has selected a rule for the selected objective

    Private m_ReplayMode As Boolean = False

    Private m_DeploymentZoneColor As Color = Color.FromArgb(120, 150, 150, 255)
    Private m_OpposingZoneColor As Color = Color.FromArgb(120, 120, 60, 60)

    Private m_ShowZOC As TriState = True
    Private m_ShowLOS As TriState = True
    Private m_ShowDeploymentZones As Boolean = True
    Private m_ShowRuleRange As Boolean = True
    Private m_ShowWaypoints As TriState = True

    Private m_ShowObjectives As TriState = TriState.True
    Private m_ShowBoundaries As Boolean = True
    Private m_ShowScale As TriState = TriState.False ' grid and scale, scale, none

    Private m_iconWidth As Int16 = 24
    Private m_iconHeight As Int16 = 24
    Private m_ShowSelectedObjectiveRuleRanges As Boolean = False
    Private m_ShowAllObjectiveRuleRanges As Boolean = False
    Private m_SelectedDeploymentZone As cmplib01.DeploymentZone
    Private m_SelectedChit As ChitMember
    Private m_ShowMapOnly As Boolean = True

    Private _replayStart As Long
    Private _replayEnd As Long
    Private iPhaseNumber As Long '// this is the replay turn

    Friend WithEvents mnuUnits As System.Windows.Forms.ContextMenuStrip ' this is used to show no units or anything else (for before login and such)

    Private m_BattleIconSize As BattleIconSize = BattleIconSize.Normal


#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        secondaryinitialize()

        'Add any initialization after the InitializeComponent() call


    End Sub

    'UserControl overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.mnuUnits = New System.Windows.Forms.ContextMenuStrip(Me.components)
        Me.SuspendLayout()
        '
        'mnuUnits
        '
        Me.mnuUnits.Name = "mnuUnits"
        Me.mnuUnits.Size = New System.Drawing.Size(153, 26)
        '
        'FlexMapViewCampaignBuilder
        '
        Me.Name = "FlexMapViewCampaignBuilder"
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

#End Region

    Private Sub SecondaryInitialize()
        Try
            '// bind the events to their overlord masters
            AddHandler picDisplay.MouseUp, AddressOf picDisplay_MouseUp
            AddHandler picDisplay.MouseMove, AddressOf picDisplay_MouseMove
            AddHandler picDisplay.MouseDown, AddressOf picDisplay_MouseDown

            '// rule colors... we can have as many as we want. Perhaps I will add them ad infinitum.
            m_RuleColor(0) = Color.Crimson
            m_RuleColor(1) = Color.Green
            m_RuleColor(2) = Color.Brown
            m_RuleColor(3) = Color.Blue
            m_RuleColor(4) = Color.SteelBlue
            m_RuleColor(5) = Color.DarkBlue
            m_RuleColor(6) = Color.DarkGoldenrod
            m_RuleColor(7) = Color.DarkGreen
            m_RuleColor(8) = Color.DarkKhaki
            m_RuleColor(9) = Color.DarkOrange
            m_RuleColor(10) = Color.DarkSlateBlue

            tmrReplay.Interval = 250

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try

    End Sub


#Region "picDisplay Events"
    Private Shadows Sub picDisplay_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 'Handles picDisplay.MouseUp
        Try
            Dim j As New System.Windows.Forms.MouseEventArgs(e.Button, e.Clicks, CInt((e.X - MyBase.OffSetX) / (MyBase.ZoomFactor) / (MyBase.ZoomFactor)), CInt((e.Y - MyBase.OffSetY) / MyBase.ZoomFactor / (MyBase.ZoomFactor)), e.Delta)
            RaiseEvent DisplayClick(sender, j)
        Catch ex As Exception

        End Try
    End Sub

    Private Sub picDisplay_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 'Handles picDisplay.MouseMove
        Try
            Dim j As New System.Windows.Forms.MouseEventArgs(e.Button, e.Clicks, CInt((e.X - MyBase.OffSetX) / MyBase.ZoomFactor), CInt((e.Y - MyBase.OffSetY) / MyBase.ZoomFactor), e.Delta)
            RaiseEvent DisplayMouseMove(j)
        Catch ex As Exception

        End Try
    End Sub

    Private Sub picDisplay_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 'Handles picDisplay.MouseDown
        Try
            Dim j As New System.Windows.Forms.MouseEventArgs(e.Button, e.Clicks, CInt((e.X - MyBase.OffSetX) / MyBase.ZoomFactor), CInt((e.Y - MyBase.OffSetY) / MyBase.ZoomFactor), e.Delta)
            RaiseEvent DisplayMouseDown(j)
        Catch ex As Exception

        End Try
    End Sub
#End Region



#Region "Properties"

    Public Property replayStart() As Long
        Get
            Return _replayStart
        End Get
        Set(ByVal value As Long)
            _replayStart = value
        End Set
    End Property

    Public Property replayEnd() As Long
        Get
            Return _replayEnd
        End Get
        Set(ByVal value As Long)
            _replayEnd = value
        End Set
    End Property

    Public Property BattleIcon() As BattleIconSize
        Get
            Return m_BattleIconSize
        End Get
        Set(ByVal Value As BattleIconSize)
            m_BattleIconSize = Value
        End Set
    End Property

    'Public Property PhaseCount() As Integer
    '    Get
    '        Return m_phaseCount
    '    End Get
    '    Set(ByVal Value As Integer)
    '        m_phaseCount = Value
    '    End Set
    'End Property

    Public Property ReplayMode() As Boolean
        Get
            Return m_ReplayMode
        End Get
        Set(ByVal Value As Boolean)
            m_ReplayMode = Value
            If m_ReplayMode Then
                'iPhaseNumber = 0
                tmrReplay.Enabled = True
            Else
                tmrReplay.Enabled = False
            End If
        End Set
    End Property

    Public Property CurrentGameData() As cmplib01.CampaignerGameData
        Get
            Return ptrCurrentGameData
        End Get
        Set(ByVal Value As cmplib01.CampaignerGameData)
            ptrCurrentGameData = Value
        End Set
    End Property

    Public Property SelectedDeploymentZone() As DeploymentZone
        Get
            Return m_SelectedDeploymentZone

        End Get
        Set(ByVal Value As DeploymentZone)
            m_SelectedDeploymentZone = Value
            RedrawMap()
        End Set
    End Property

    Public Property SelectedChit() As ChitMember
        Get
            Return m_SelectedChit
        End Get
        Set(ByVal Value As ChitMember)
            m_SelectedChit = Value
            If Not Value Is Nothing Then
                RaiseEvent ChitSelected(m_SelectedChit)
            End If
        End Set
    End Property

    Public ReadOnly Property RuleColor(ByVal index As Byte) As Color
        Get
            If index > 10 Then index = 10
            Return m_RuleColor(index)
        End Get
    End Property

    Public Property ShowSelectedObjectiveRuleRanges() As Boolean
        Get
            Return m_ShowSelectedObjectiveRuleRanges
        End Get
        Set(ByVal Value As Boolean)
            m_ShowSelectedObjectiveRuleRanges = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowAllObjectiveRuleRanges() As Boolean
        Get
            Return m_ShowAllObjectiveRuleRanges
        End Get
        Set(ByVal Value As Boolean)
            m_ShowAllObjectiveRuleRanges = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowLOS() As TriState
        Get
            Return m_ShowLOS
        End Get
        Set(ByVal Value As TriState)
            m_ShowLOS = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowZOC() As TriState
        Get
            Return m_ShowZOC
        End Get
        Set(ByVal Value As TriState)
            m_ShowZOC = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowDeploymentZones() As Boolean
        Get
            Return m_ShowDeploymentZones
        End Get
        Set(ByVal Value As Boolean)
            m_ShowDeploymentZones = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowWaypoints() As TriState
        Get
            Return m_ShowWaypoints
        End Get
        Set(ByVal Value As TriState)
            m_ShowWaypoints = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowBoundaries() As Boolean
        Get
            Return m_ShowBoundaries
        End Get
        Set(ByVal Value As Boolean)
            m_ShowBoundaries = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowObjectives() As TriState
        Get
            Return m_ShowObjectives
        End Get
        Set(ByVal Value As TriState)
            m_ShowObjectives = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowScaleAndGrid() As TriState
        Get
            Return m_ShowScale
        End Get
        Set(ByVal Value As TriState)
            m_ShowScale = Value
            RedrawMap()
        End Set
    End Property

    Public Property ShowMapOnly() As Boolean
        Get
            Return m_ShowMapOnly
        End Get
        Set(ByVal Value As Boolean)
            m_ShowMapOnly = Value
            RedrawMap()
        End Set
    End Property

    Public Property IconSize() As Int16
        Get
            Return m_iconWidth
        End Get
        Set(ByVal Value As Int16)
            m_iconWidth = Value
            m_iconHeight = Value
        End Set
    End Property

#End Region

    Public Sub DrawLOSRays(ByVal pnt As Point, ByVal LOSRange As Integer, Optional ByVal Power As Single = 1)
        '// draws LOS rays from the point up to the range... yeah
        Dim MoveStep As Single = 5

        Dim g As Graphics = MyBase.picDisplay.CreateGraphics

        Try
            Dim target As New PointF
            Dim sm As New SMVector
            Dim samplePoint As New PointF(pnt.X + LOSRange, pnt.Y)
            Dim offsetstep As Integer = 20
            Dim totalCost As Single

            '// a little ineffecient, but were testing
            Dim q1path As New GraphicsPath
            Dim q2path As New GraphicsPath
            Dim q3path As New GraphicsPath
            Dim q4path As New GraphicsPath

            Dim q1pointsies As New ArrayList(10)
            Dim q2pointsies As New ArrayList(10)
            Dim q3pointsies As New ArrayList(10)
            Dim q4pointsies As New ArrayList(10)

            Dim adjLOSRange As Single = LOSRange * FMPData.PixelsPerOneMile
            Dim LOSCost As Single
            Dim diff As Single

            Dim sampXoffset As Single = adjLOSRange
            Dim sampYoffset As Single = 0

            Dim done As Boolean
            Dim i As Integer

            'q1
            sampXoffset = adjLOSRange
            sampYoffset = 0
            q1pointsies.Add(New PointF(pnt.X, pnt.Y))

            Do Until sampXoffset < 0

                target.X = pnt.X + (sampXoffset)
                target.Y = pnt.Y + (sampYoffset)

                target = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, adjLOSRange / 2)

                'MyBase.DrawVertex(g, target, 6, Color.Red)

                done = False
                i = 0
                totalCost = 0
                Do Until done
                    i += MoveStep
                    samplePoint = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, i)

                    LOSCost = FMPData.LOSCost(New Point(samplePoint.X, samplePoint.Y))
                    If LOSCost > 1 Then
                        diff = LOSCost - 1
                        diff *= Power
                        LOSCost = diff + 1
                        If LOSCost < 1 Then LOSCost = 1
                    End If

                    totalCost += LOSCost * MoveStep

                    'MyBase.DrawVertex(g, samplePoint, 4, Color.Yellow)
                    If totalCost >= adjLOSRange / 2 Then
                        q1pointsies.Add(New PointF(samplePoint.X, samplePoint.Y))
                        done = True
                    End If
                Loop

                sampXoffset -= offsetstep
                sampYoffset += offsetstep
            Loop


            'q2
            sampXoffset = adjLOSRange
            sampYoffset = 0
            q2pointsies.Add(New PointF(pnt.X, pnt.Y))

            Do Until sampXoffset < 0

                target.X = pnt.X + (sampXoffset)
                target.Y = pnt.Y + (sampYoffset)

                target = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, adjLOSRange / 2)

                'MyBase.DrawVertex(g, target, 6, Color.Red)

                done = False
                i = 0
                totalCost = 0
                Do Until done
                    i += MoveStep
                    samplePoint = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, i)

                    LOSCost = FMPData.LOSCost(New Point(samplePoint.X, samplePoint.Y))
                    If LOSCost > 1 Then
                        diff = LOSCost - 1
                        diff *= Power
                        LOSCost = diff + 1
                        If LOSCost < 1 Then LOSCost = 1
                    End If

                    totalCost += LOSCost * MoveStep

                    'MyBase.DrawVertex(g, samplePoint, 4, Color.Yellow)
                    If totalCost >= adjLOSRange / 2 Then
                        q2pointsies.Add(New PointF(samplePoint.X, samplePoint.Y))
                        done = True
                    End If
                Loop

                sampXoffset -= offsetstep
                sampYoffset -= offsetstep
            Loop



            'q3
            sampXoffset = -1 * adjLOSRange
            sampYoffset = 0
            q3pointsies.Add(New PointF(pnt.X, pnt.Y))

            Do Until sampXoffset >= offsetstep

                target.X = pnt.X + (sampXoffset)
                target.Y = pnt.Y + (sampYoffset)

                target = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, adjLOSRange / 2)

                'MyBase.DrawVertex(g, target, 6, Color.Red)

                done = False
                i = 0
                totalCost = 0
                Do Until done
                    i += MoveStep
                    samplePoint = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, i)

                    LOSCost = FMPData.LOSCost(New Point(samplePoint.X, samplePoint.Y))
                    If LOSCost > 1 Then
                        diff = LOSCost - 1
                        diff *= Power
                        LOSCost = diff + 1
                        If LOSCost < 1 Then LOSCost = 1
                    End If

                    totalCost += LOSCost * MoveStep

                    'MyBase.DrawVertex(g, samplePoint, 4, Color.Yellow)
                    If totalCost >= adjLOSRange / 2 Then
                        q3pointsies.Add(New PointF(samplePoint.X, samplePoint.Y))
                        done = True
                    End If
                Loop

                sampXoffset += offsetstep
                sampYoffset += offsetstep
            Loop

            'q4()
            sampXoffset = -1 * adjLOSRange
            sampYoffset = 0
            q4pointsies.Add(New PointF(pnt.X, pnt.Y))

            Do Until sampXoffset >= offsetstep

                target.X = pnt.X + (sampXoffset)
                target.Y = pnt.Y + (sampYoffset)

                target = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, adjLOSRange / 2)

                'MyBase.DrawVertex(g, target, 6, Color.Red)

                done = False
                i = 0
                totalCost = 0
                Do Until done
                    i += MoveStep
                    samplePoint = sm.GeneratePtOnVector(New PointF(pnt.X, pnt.Y), target, i)

                    LOSCost = FMPData.LOSCost(New Point(samplePoint.X, samplePoint.Y))
                    If LOSCost > 1 Then
                        diff = LOSCost - 1
                        diff *= Power
                        LOSCost = diff + 1
                        If LOSCost < 1 Then LOSCost = 1
                    End If

                    totalCost += LOSCost * MoveStep

                    'MyBase.DrawVertex(g, samplePoint, 4, Color.Yellow)
                    If totalCost >= adjLOSRange / 2 Then
                        q4pointsies.Add(New PointF(samplePoint.X, samplePoint.Y))
                        done = True
                    End If
                Loop

                sampXoffset += offsetstep
                sampYoffset -= offsetstep
            Loop

            Dim obrush As New SolidBrush(Color.FromArgb(155, 255, 255, 255))


            ' now... draw the LOS ... path circle thingie
            For i = 1 To q1pointsies.Count - 1
                q1path.AddLine(q1pointsies.Item(i - 1), q1pointsies.Item(i))
            Next
            g.FillPath(obrush, q1path)

            For i = 1 To q2pointsies.Count - 1
                q2path.AddLine(q2pointsies.Item(i - 1), q2pointsies.Item(i))
            Next
            g.FillPath(obrush, q2path)

            For i = 1 To q3pointsies.Count - 1
                q3path.AddLine(q3pointsies.Item(i - 1), q3pointsies.Item(i))
            Next
            g.FillPath(obrush, q3path)

            For i = 1 To q4pointsies.Count - 1
                q4path.AddLine(q4pointsies.Item(i - 1), q4pointsies.Item(i))
            Next
            g.FillPath(obrush, q4path)

            obrush.Dispose()


        Catch ex As Exception
            HandleException("Campaigner Combat Engine.PointToPointDetection", ex)
        Finally
            g.Dispose()
        End Try

    End Sub

    Private Sub tmrReplay_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrReplay.Tick
        Try
            RenderToDisplay()
            'TASK: replay tick

            iPhaseNumber += 1
            If iPhaseNumber > _replayEnd Then
                iPhaseNumber = _replayStart
                '// we can end the replay, yeah?
                tmrReplay.Enabled = False
                RaiseEvent ReplayEnded()
            End If

            RaiseEvent ReplayTurnDrawn(iPhaseNumber)
        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Public Sub DrawSingleRuleRange(ByVal active As Boolean, ByVal radius As Int32, ByVal location As Point)
        ' sets up the internal show this rule attribute for redrawing. This is to display the rule range of ONE rule per selected
        ' objective only.
        showRule.ShowThis = active
        showRule.RuleRange = radius
        showRule.RuleLocation = location
        RedrawMap()

    End Sub

    Public Sub DeleteSelected()
        ' deletes the selected item
        If m_SelectedChit Is Nothing Then Exit Sub
        ptrCurrentGameData.Chits.remove(m_SelectedChit)
    End Sub


    Public Function SelectChit(ByVal pnt As Point) As Boolean
        ' returns true if a chit has been selected
        'Dim key As String
        'Dim chit As GroundChitType
        Dim lastDistance As Int16 = c_SelectionDistance / MyBase.ZoomFactor
        Dim bSelected As Boolean = False

        '// this is the close enough list
        Dim members As New ChitMembers
        Dim selmem As ChitMember

        Try

            isChitSelected = False

            If SelectedPlayerFaction Is Nothing Then Exit Function

            For Each mem As ChitMember In ptrCurrentGameData.Chits
                If XYDistance(pnt, mem.Location) <= c_SelectionDistance Then
                    members.add(mem)
                End If
            Next

            Select Case members.Count
                Case Is = 0
                    Exit Function
                Case Is = 1
                    selmem = members.item(0)
                    DoSelect(selmem)
                    RaiseEvent ChitSelected(selmem)
                    bSelected = True
                Case Is > 1
                    '// popup... goodness gracious.
                    Me.mnuUnits.Items.Clear()
                    Dim index As Integer
                    Dim sysEveHandler As New System.EventHandler(AddressOf MenuSelectChit)
                    For Each closemember As ChitMember In members
                        If closemember.UnitType = GroundChitClass_cgd.Objective Then
                            mnuUnits.Items.Add(closemember.Name, DirectCast(closemember, InstallationChit).ptrInstallation.Icon(0), sysEveHandler)
                        Else
                            mnuUnits.Items.Add(closemember.Name, closemember.icon, sysEveHandler)
                        End If

                        mnuUnits.Items(index).Tag = closemember
                        index += 1
                    Next
                    mnuUnits.Show(Me, pnt.X, pnt.Y)
            End Select

            Return bSelected
        Catch ex As Exception
            HandleException("FlexMapViewCampaignBuilder.SelectChit", ex)
        End Try

    End Function

    Private Function DoSelect(ByRef chit As ChitMember) As ChitSelectionResult
        'Dim thisDistance As Int16
        Dim SelectResult As ChitSelectionResult = ChitSelectionResult.NoSelection
        'Dim bDoneSelect As Boolean

        ' determine if its close enough to be selected
        'thisDistance = XYDistance(chit.Location.X, pnt.X, chit.Location.Y, pnt.Y)

        'If thisDistance < lastDistance Then
        ' select the objective
        If chit Is m_SelectedChit Then
            ' deselect the chit
            m_SelectedChit = Nothing
            '   bDoneSelect = True
            isChitSelected = False
            Return ChitSelectionResult.ChitSelected
        End If
        m_SelectedChit = chit
        'lastDistance = thisDistance
        isChitSelected = True
        SelectResult = ChitSelectionResult.ChitSelected
        'End If

        Return SelectResult

    End Function

    Private Sub MenuSelectChit(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim selmem As ChitMember = sender.tag
        DoSelect(selmem)

        RaiseEvent ChitSelected(selmem)
    End Sub


    Public Function SelectDeploymentZone(ByVal pnt As Point) As Boolean
        ' returns true if a deploymentzone has been selected

    End Function

    Overrides Sub RenderToDisplay()
        If Not MyBase.FMP Is Nothing Then
            If MyBase.Rendered_b = False Then Exit Sub
            Dim im As Image = New Bitmap(CInt(MyBase.FMP.Width * MyBase.ZoomFactor), CInt(MyBase.FMP.Height * MyBase.ZoomFactor))
            Dim g As Graphics = Graphics.FromImage(im)

            setposition()

            ' scale if necessary
            If MyBase.ZoomFactor <> -1 Then
                g.ScaleTransform(MyBase.ZoomFactor, MyBase.ZoomFactor)
            End If
            ' removed the zoomfactor from here

            If bEditable = True Then
                MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , -1, -1)
            Else
                If m_MapOpened = True Then
                    MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , -1, -1, , , , False)
                Else
                    MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , -1, -1)
                End If
            End If

            'If bEditable = True Then
            '    MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , MyBase.ZoomFactor, MyBase.ZoomFactor)
            'Else
            '    If m_MapOpened = True Then
            '        MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , MyBase.ZoomFactor, MyBase.ZoomFactor, , , , False)
            '    Else
            '        MyBase.FMP.Render(g, g.VisibleClipBounds, MyBase.ShowPaths, , MyBase.ZoomFactor, MyBase.ZoomFactor)
            '    End If
            'End If

            'add bridges and labels
            MyBase.DrawRoads(g)
            DrawBridges(g)
            DrawLabels(g)

            ' grid and scale
            If m_ShowScale = TriState.True Then
                MyBase.showGrid = True
                MyBase.showScale = True
                MyBase.DrawGrid(g)
                MyBase.DrawScale(g)
            ElseIf m_ShowScale = TriState.UseDefault Then
                MyBase.showGrid = False
                MyBase.showScale = True
                MyBase.DrawScale(g)
            End If

            ' boundaries
            DrawBoundaries(g)

            If m_ShowMapOnly = False Then

                ' area objectives
                DrawAreaObjectives(g)

                ' draw ZOCs, los ranges and rule ranges, boundaries
                DrawOptions(g)

                ' and deployment zones
                DrawDeploymentZones(g)

                ' draw chits
                DrawChits(g)

                ' and battles!
                DrawBattles(g)

                ' single rule range if 'active'
                If showRule.ShowThis = True Then
                    DrawBorderedCircle(g, showRule.RuleLocation, showRule.RuleRange, Color.Black, Color.Yellow)
                End If
            End If

            picDisplay.Image = im
            MyBase.BMP = im

            g.Dispose()
            GC.Collect()

            MyBase.Rendered_b = True
            RaiseEvent Rendered()
        End If
    End Sub

    Private Sub DrawOptions(ByRef g As Graphics)
        If ptrCurrentGameData Is Nothing Then Exit Sub
        If m_ReplayMode Then Exit Sub

        ' make sure we have the correct faction
        If Not ptrCurrentGameData.selectedPlayer Is Nothing Then SelectedPlayerFaction = ptrCurrentGameData.Faction_g.Item(ptrCurrentGameData.selectedPlayer.FactionKey)

        'Dim gc As cmplib01.GroundChitType
        'Dim key As String

        Dim pixelsPerOneMile As Integer = MyBase.FMPData.MapScale.PixelCount / MyBase.FMPData.MapScale.MilesPerPixelCount

        For Each mem As ChitMember In ptrCurrentGameData.Chits
            Dim pnt As Point
            Dim optionPoint As Point

            pnt = mem.Location
            pnt.X -= (m_iconWidth / 2) / MyBase.ZoomFactor
            pnt.Y -= (m_iconHeight / 2) / MyBase.ZoomFactor
            optionPoint.X = mem.Location.X
            optionPoint.Y = mem.Location.Y

            If mem.OwningFaction.Equals(SelectedPlayerFaction) Then

                '// wow. This is dumb. We go through the list TWICE to draw stuff. 
                'HACK: going through the unit list twice to draw los and chits.
                Select Case mem.Status
                    Case GroundUnitStatus_cgd.Assembling, GroundUnitStatus_cgd.Engaged, GroundUnitStatus_cgd.Moving, GroundUnitStatus_cgd.OK, GroundUnitStatus_cgd.Regrouping, GroundUnitStatus_cgd.Reinforcing
                        ' zoc 
                        If m_ShowZOC And mem.ZOC > 0 Then
                            If m_ShowZOC = TriState.True Then
                                DrawZOC(g, optionPoint, mem.ZOC * pixelsPerOneMile, , mem.Status)
                            Else
                                If mem Is m_SelectedChit Then DrawZOC(g, optionPoint, mem.ZOC * pixelsPerOneMile, , m_SelectedChit.Status)
                            End If
                        End If

                        ' chit
                        If mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                            DrawFilledRectangle(g, pnt.X - 2, pnt.Y - 2, CInt((m_iconWidth / MyBase.ZoomFactor) + 4), CInt((m_iconWidth / MyBase.ZoomFactor) + 4))
                        End If

                        ' los
                        If m_ShowLOS And (mem.LOS > 0) Then
                            If m_ShowLOS = TriState.True Then
                                'Dim losRange As Integer
                                DrawBorderedCircle(g, optionPoint, (mem.LOS) * pixelsPerOneMile, Color.Black, Color.White)
                            Else
                                If mem Is m_SelectedChit Then DrawBorderedCircle(g, optionPoint, (mem.LOS) * pixelsPerOneMile, Color.Black, Color.White)
                            End If
                        End If

                        ' reinforcement range, currently always drawing it. shahaa!
                        If mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                            'DrawBorderedCircle(g, optionPoint, (DirectCast(mem, BattlegroupChit).effectiveReinforcement * pixelsPerOneMile), Color.Black, Color.Yellow)
                            drawReinforcementRange(g, optionPoint, (DirectCast(mem, BattlegroupChit).effectiveReinforcement * pixelsPerOneMile))
                        End If

                        ' waypoints
                        If m_ShowWaypoints <> TriState.False Then
                            If m_ShowWaypoints = TriState.True Then
                                ' show all waypoints
                                DrawWaypoints(g, mem)
                            Else  ' show only SELECTED unit waypoints
                                If mem Is m_SelectedChit Then DrawWaypoints(g, mem)
                            End If
                        End If
                End Select

            End If

            ' now do the rule ranges if those options are set, but never show the enemy rule range
            If m_ShowSelectedObjectiveRuleRanges = True Then
                If Not m_SelectedChit Is Nothing Then
                    If mem Is m_SelectedChit Then DrawRuleRange(g, m_SelectedChit)
                End If
            ElseIf m_ShowAllObjectiveRuleRanges = True Then
                DrawRuleRange(g, mem)
            End If

        Next
    End Sub

    Private Sub drawReinforcementRange(ByRef g As Graphics, ByRef loc As Point, ByVal radius As Integer)

        Dim bl As New System.Drawing.Drawing2D.HatchBrush(Drawing2D.HatchStyle.SmallCheckerBoard, Color.DarkGreen, Color.Blue)

        g.SmoothingMode = SmoothingMode.HighSpeed

        Dim pa As New GraphicsPath()
        pa.AddEllipse(New Rectangle(loc.X - radius / 2 - 3, loc.Y - radius / 2 - 3, radius + 6, radius + 6))
        Dim cu As New GraphicsPath
        cu.AddEllipse(New Rectangle(loc.X - radius / 2, loc.Y - radius / 2, radius, radius))

        Dim reg As New Region
        reg.Intersect(pa)
        reg.Exclude(cu)

        g.FillRegion(bl, reg)
        g.DrawEllipse(Pens.Black, CInt(loc.X - radius / 2 - 3), CInt(loc.Y - radius / 2 - 3), radius + 6, radius + 6)
        g.DrawEllipse(Pens.LightBlue, (New Rectangle(loc.X - radius / 2, loc.Y - radius / 2, radius, radius)))

    End Sub

    Private Sub DrawBoundaries(ByRef g As Graphics)
        If ptrCurrentGameData Is Nothing Then Exit Sub
        If m_ShowBoundaries = False Then Exit Sub
        If m_ReplayMode Then Exit Sub

        Dim bound As GenericBoundary

        Try
            For Each bound In ptrCurrentGameData.Boundaries
                Dim zonePath As New System.Drawing.Drawing2D.GraphicsPath
                Dim pnt As PointF
                Dim lastPnt As PointF
                Dim i As Int16
                Dim boundaryPen As New Pen(bound.BoundaryColor, bound.BoundaryWidth)
                boundaryPen.DashStyle = bound.BoundaryStyle
                For Each pnt In bound.BoundaryPath.Points
                    If i <> 0 Then
                        zonePath.AddLine(lastPnt, pnt)
                        lastPnt = pnt
                    Else
                        lastPnt = pnt
                    End If
                    i += 1
                Next
                i = 0
                If bound.IsSelected Then
                    Dim selectedPen As New Pen(Color.Yellow, bound.BoundaryWidth + 2)
                    selectedPen.DashStyle = Drawing.Drawing2D.DashStyle.Solid
                    g.DrawPath(selectedPen, zonePath)
                    g.DrawPath(boundaryPen, zonePath)
                Else
                    g.DrawPath(boundaryPen, zonePath)
                End If

            Next

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub DrawAreaObjectives(ByRef g As Graphics)
        If ptrCurrentGameData Is Nothing Then Exit Sub
        If m_ShowObjectives = TriState.False Then Exit Sub
        If m_ReplayMode = True Then Exit Sub

        Dim AO As AreaObjective

        Dim OwnedAO As New HatchBrush(HatchStyle.Cross, Color.FromArgb(30, 220, 220, 220), Color.FromArgb(120, 20, 120, 20))
        Dim UncontrolledAO As New HatchBrush(HatchStyle.WideUpwardDiagonal, Color.FromArgb(30, 220, 220, 220), Color.FromArgb(120, 20, 20, 20))
        Dim EnemyAO As New HatchBrush(HatchStyle.Cross, Color.FromArgb(30, 120, 20, 20), Color.FromArgb(120, 120, 20, 20))
        Dim ContestedAO As New HatchBrush(HatchStyle.WideDownwardDiagonal, Color.FromArgb(100, 220, 20, 20), Color.FromArgb(100, 20, 220, 20))

        Try
            For Each AO In ptrCurrentGameData.AreaObjectives
                Dim zonePath As New System.Drawing.Drawing2D.GraphicsPath
                Dim pnt As PointF
                Dim lastPnt As PointF
                Dim i As Int16

                For Each pnt In AO.BoundaryPath.Points
                    If i <> 0 Then
                        zonePath.AddLine(lastPnt, pnt)
                        lastPnt = pnt
                    Else
                        lastPnt = pnt
                    End If
                    i += 1
                Next
                i = 0
                ' determine who's pov we are in and create the brush

                'Dim AOBrush As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.Cross, Color.FromArgb(30, 220, 220, 220), Color.FromArgb(120, 20, 120, 20))
                Dim AOBrush As Drawing2D.HatchBrush

                If AO.OwningFaction = -1 Then
                    AOBrush = UncontrolledAO
                ElseIf AO.OwningFaction = ptrCurrentGameData.selectedFaction.FactionID Then
                    AOBrush = OwnedAO
                Else
                    AOBrush = EnemyAO
                End If
                ' down here we catch finally if its contested
                If AO.IsContested Then
                    AOBrush = ContestedAO
                End If

                g.FillPath(AOBrush, zonePath)

                ' if this one is selected, yellow the border
                If AO.IsSelected Then
                    g.DrawPath(Pens.Yellow, zonePath)
                Else
                    g.DrawPath(Pens.Black, zonePath)
                End If

                ' draw the name
                If m_ShowObjectives = TriState.True Then
                    Dim boundRect As RectangleF
                    boundRect = AO.ObjectiveRegion.GetBounds(g)
                    ' TODO: Smarter deploymentzone name viewing
                    g.DrawString(AO.BoundaryName, Me.Font, Brushes.Black, boundRect.X + (boundRect.Width / 4), boundRect.Y + (boundRect.Height / 4))
                End If
                
            Next
        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try

    End Sub

    Private Sub DrawRuleRange(ByRef g As Graphics, ByRef mem As ChitMember)
        'Dim rul As Rule
        'Dim rult As RuleType
        'Dim key As String
        Dim pnt As Point
        Dim colorIndex As Byte
        Dim pixelsPerOneMile As Integer = MyBase.FMPData.MapScale.PixelCount / MyBase.FMPData.MapScale.MilesPerPixelCount

        'objType = Objective
        pnt = mem.Location

        If mem.chitRules.Count > 0 Then

            For Each ru As Rule In mem.chitRules
                DrawBorderedCircle(g, pnt, (ru.ptrRule.BasicRange * pixelsPerOneMile), m_RuleColor(colorIndex), Color.Black)
                colorIndex += 1
                If colorIndex = 11 Then colorIndex = 0
            Next

            'For Each key In objType.ObjectiveRules.HT.Keys
            '    rul = objType.ObjectiveRules.Item(key)
            '    ' find the correct rule type and get its range
            '    rult = ptrCurrentGameData.RuleTypes_g.Item(cmplib01.CampaignerGameData.CDGKEY_RULETYPE & rul.ruleTypeID)
            '    DrawBorderedCircle(g, pnt, (rult.BasicRange * pixelsPerOneMile), m_RuleColor(colorIndex), Color.Black)
            '    colorIndex += 1
            '    If colorIndex = 11 Then colorIndex = 0
            'Next
        End If
    End Sub

    Private Sub DrawDeploymentZones(ByRef g As Graphics)
        If ptrCurrentGameData Is Nothing Then Exit Sub
        If m_ShowDeploymentZones = False Then Exit Sub
        If m_ReplayMode = True Then Exit Sub

        Try
            Dim deploymentBrush As New SolidBrush(m_DeploymentZoneColor)
            'Dim deploymentbrush As New HatchBrush(HatchStyle.Cross, Color.FromArgb(10, 10, 80, 10), Color.FromArgb(120, 10, 80, 10))
            Dim key As String
            Dim dep As New cmplib01.DeploymentZone

            For Each key In ptrCurrentGameData.DeploymentZones_g.HT.Keys
                dep = ptrCurrentGameData.DeploymentZones_g.Item(key)
                Dim zonePath As New System.Drawing.Drawing2D.GraphicsPath
                Dim pnt As PointF
                Dim lastPnt As PointF
                Dim i As Int16
                Dim reg As New Region
                Dim boundRect As RectangleF
                ' if there are points available for deployment, go ahead and draw the zone. If not, don't draw it.
                If dep.MaxDeploymentPerTurn - dep.PointsDeployedThisTurn > 0 Then
                    For Each pnt In dep.BoundaryPath.Points
                        If i <> 0 Then
                            zonePath.AddLine(lastPnt, pnt)
                            lastPnt = pnt
                        Else
                            lastPnt = pnt
                        End If
                        i += 1
                    Next
                    i = 0
                    If SelectedPlayerFaction.FactionID = dep.FactionID Then
                        deploymentBrush.Color = m_DeploymentZoneColor
                        'deploymentBrush.ForegroundColor = m_DeploymentZoneColor
                        g.FillPath(deploymentBrush, zonePath)
                        zonePath.CloseAllFigures()
                        ' now, we get a bounding rectangle and write the deployment zone name in the center
                        reg.Intersect(zonePath)
                        boundRect = reg.GetBounds(g)
                        ' TODO: Smarter deploymentzone name viewing
                        g.DrawString(dep.ZoneName, Me.Font, Brushes.Black, boundRect.X + (boundRect.Width / 4), boundRect.Y + (boundRect.Height / 4))
                        g.DrawString(dep.MaxTotalDeploy.ToString & " total", Me.Font, Brushes.Black, boundRect.X + (boundRect.Width / 4), boundRect.Y + (boundRect.Height / 4) + 12)
                        g.DrawString("(" & dep.MaxDeploymentPerTurn - dep.PointsDeployedThisTurn & " this turn)", Me.Font, Brushes.Black, boundRect.X + (boundRect.Width / 4), boundRect.Y + (boundRect.Height / 4) + 24)
                    End If
                End If
            Next
            deploymentBrush.Dispose()
        Catch argEx As ArgumentOutOfRangeException
            ' whew. 
        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub DrawChits(ByRef g As Graphics)

        If ptrCurrentGameData Is Nothing Then Exit Sub
        '// THIS is a mutha mukkin mess. What on Ert shall I do with it?

        Dim key As String

        'selectedplayerfaction.HTChitDetection, this includes objectives
        Dim det As ChitDetection
        Dim target As ChitMember
        Dim drawOK As Boolean = False

        Dim enemyBorderPen As New Pen(Color.Red, 3)
        Dim fBorderPen1 As New Pen(Color.Yellow, 3)
        Dim fBorderPen2 As New Pen(Color.Black, 3)

        Try

            If ReplayMode = True Then
                For Each mem As ChitMember In ptrCurrentGameData.Chits

                    If Not mem.OwningFaction.Equals(ptrCurrentGameData.selectedFaction) Then
                        '// more catching the old stuff
                        If mem.detectionStatus Is Nothing Then mem.detectionStatus = New Hashtable

                        Dim deteve As HistoricalDetectionStatusEntry = mem.detectionStatus.Item(iPhaseNumber)
                        '// see if there is an entry for detection for this phase
                        If Not deteve Is Nothing Then
                            If mem.UnitType = GroundChitClass_cgd.Objective Then
                                Select Case deteve.detectionStatus
                                    Case ChitDetectionLevel_cdl.Dead
                                        g.DrawImage(picEnemyDead.Image, mem.Location.X, mem.Location.Y, m_iconWidth, m_iconHeight)
                                    Case ChitDetectionLevel_cdl.Undetected
                                    Case ChitDetectionLevel_cdl.Detected
                                        '// this is the almighty question mark
                                        g.DrawImage(Me.picVacantImage.Image, CInt(mem.Location.X - (m_iconWidth / 2)), CInt(mem.Location.Y - (m_iconHeight / 2)), m_iconWidth, m_iconHeight)
                                    Case Else
                                        g.DrawImage(DirectCast(mem, InstallationChit).ptrInstallation.Icon(0), CInt(mem.Location.X - (m_iconWidth / 2)), CInt(mem.Location.Y - (m_iconHeight / 2)), m_iconWidth, m_iconHeight)
                                End Select
                            ElseIf mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                                Dim bg As BattlegroupChit = mem

                                Select Case deteve.detectionStatus
                                    Case ChitDetectionLevel_cdl.Dead
                                        g.DrawImage(picEnemyDead.Image, bg.HistoricalPosition2(iPhaseNumber).x, bg.HistoricalPosition2(iPhaseNumber).y, m_iconWidth, m_iconHeight)
                                    Case ChitDetectionLevel_cdl.Undetected
                                        '// guess who we don't draw
                                    Case ChitDetectionLevel_cdl.Detected
                                        g.DrawImage(picVacantImage.Image, bg.HistoricalPosition2(iPhaseNumber).x, bg.HistoricalPosition2(iPhaseNumber).y, m_iconWidth, m_iconHeight)
                                    Case Else
                                        g.DrawImage(bg.icon, bg.HistoricalPosition2(iPhaseNumber).x, bg.HistoricalPosition2(iPhaseNumber).y, m_iconWidth, m_iconHeight)
                                End Select
                            End If
                        End If
                    End If
                Next
            Else
                For Each key In SelectedPlayerFaction.HTChitDetection.Keys
                    det = SelectedPlayerFaction.HTChitDetection.Item(key)
                    target = det.Chit
                    Dim enemyLocation As Point = target.Location
                    '// this is for the replay
                    drawOK = False

                    'If ReplayMode Then
                    '    '//////////////////////NEW//////////////////////
                    '    '// this might cause the turn to stop before the replay is actually finished
                    '    'If target.UnitType = GroundChitClass_cgd.Battlegroup Then
                    '    '    If DirectCast(target, BattlegroupChit).historicalPosition.Count < iPhaseNumber Then iPhaseNumber = 0
                    '    'End If
                    '    '//////////////////////NEW//////////////////////

                    '    Try
                    '        If target.UnitType = GroundChitClass_cgd.Battlegroup Then
                    '            'TASK: replay
                    '            'enemyLocation = DirectCast(target, BattlegroupChit).historicalPosition(iPhaseNumber)
                    '            'enemyLocation = DirectCast(target, BattlegroupChit).HistoricalPosition2.Item(ptrCurrentGameData.replayPhaseKeys.Item(iphasenumber))
                    '        Else
                    '            enemyLocation = target.Location
                    '        End If

                    '    Catch ex As Exception
                    '    End Try
                    'Else
                    '    ' use normal position
                    '    enemyLocation = target.Location
                    'End If

                    enemyLocation = target.Location
                    enemyLocation.X -= (m_iconWidth / 2)
                    enemyLocation.Y -= (m_iconHeight / 2)

                    ' if its dead, draw it that way
                    If target.Status = GroundUnitStatus_cgd.Dead Then
                        Dim bmp As Bitmap = picEnemyDead.Image
                        bmp.MakeTransparent(Color.Magenta)
                        g.DrawImage(bmp, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                    Else

                        '// if we're in replay AND the phase is less than the phase it was detected,
                        '// don't draw it.
                        'If ReplayMode = True Then
                        'If det.PhaseDetected <= iPhaseNumber Then
                        '    drawOK = True
                        'Else
                        '    drawOK = False
                        'End If

                        'Else
                        drawOK = True
                        'End If

                        If drawOK Then
                            Select Case det.DetectionLevel
                                Case Is <= 1 : g.DrawImage(MyBase.picVacantImage.Image, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                Case Is <= 2 : g.DrawImage(MyBase.picVacantImage.Image, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                Case Else
                                    '// somehow an icon got missed in a battlegroup!
                                    Try
                                        If target.icon Is Nothing Then
                                            'HACK: Temporary fix
                                            g.DrawImage(MyBase.picBlankImage.Image, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                        Else

                                            If target.UnitType = GroundChitClass_cgd.Objective Then
                                                g.DrawImage(DirectCast(target, InstallationChit).ptrInstallation.Icon(0), enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                            Else
                                                g.DrawImage(target.icon, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                            End If

                                            '// now the proper border. RED RED RED.
                                            g.DrawRectangle(enemyBorderPen, enemyLocation.X, enemyLocation.Y, m_iconWidth, m_iconHeight)
                                        End If
                                    Catch ex As Exception
                                        MessageBox.Show("Error: " & ex.Message & " thrown by " & target.Name)
                                    End Try

                            End Select
                        End If
                    End If

                Next
            End If
        Catch nullEx As NullReferenceException
            ' remove this previously deleted chit.
            '''''''SelectedPlayerFaction.HTChitDetection.Remove(key)
#If DEBUG Then
            Debug.WriteLine("Not good")
#End If
        Catch argEx As ArgumentOutOfRangeException
            'HandleException("FlexMapViewCampaignBuilder", argEx)
        Catch ex As Exception
            HandleException("FlexMapViewCampaignBuilder", ex)
        End Try
        '// =================== end detected chits

        Try
            For Each mem As ChitMember In ptrCurrentGameData.Chits
                Dim pnt As Point
                ' get the size of the icon before zoomfactor (by cancelling out the zoomfactor)
                ' changed asll m_iconWidth, m_iconHeight to icoWidth, icoHeight
                Dim icoWidth As Int16 = m_iconWidth / ZoomFactor
                Dim icoHeight As Int16 = m_iconHeight / ZoomFactor

                If mem.UnitType = GroundChitClass_cgd.Objective Then
                    pnt = mem.Location
                Else
                    If ReplayMode Then
                        'TASK: replay

                        pnt = DirectCast(mem, BattlegroupChit).HistoricalPosition2.Item(iPhaseNumber)
                    Else
                        ' use normal position
                        pnt = mem.Location
                    End If
                End If

                pnt.X -= (icoWidth / 2)
                pnt.Y -= (icoHeight / 2)

                Select Case mem.Status
                    Case GroundUnitStatus_cgd.Assembling, GroundUnitStatus_cgd.Engaged, GroundUnitStatus_cgd.Moving, GroundUnitStatus_cgd.OK, GroundUnitStatus_cgd.Regrouped, GroundUnitStatus_cgd.Regrouping, GroundUnitStatus_cgd.Reinforcing, GroundUnitStatus_cgd.Dead
                        If mem.OwningFaction.Equals(SelectedPlayerFaction) Then
                            Try
                                If mem Is m_SelectedChit Then
                                    g.FillRectangle(Brushes.Yellow, pnt.X - 2, pnt.Y - 2, icoWidth + 4, icoHeight + 4)
                                End If

                                If mem.Status = GroundUnitStatus_cgd.Dead Then
                                    '// if its dead, draw it that way
                                    Dim bmp As Bitmap = picFriendlyDead.Image
                                    bmp.MakeTransparent(Color.Magenta)
                                    g.DrawImage(bmp, pnt.X, pnt.Y, icoWidth, icoHeight)

                                Else

                                    If mem.UnitType = GroundChitClass_cgd.Objective Then
                                        '// its an objective
                                        'mem.icon.MakeTransparent(Color.Magenta)
                                        g.DrawImage(DirectCast(mem, InstallationChit).ptrInstallation.Icon(0), pnt.X, pnt.Y, icoWidth, icoHeight)
                                    Else
                                        '// its a battlegroup

                                        '// temporary draw reinforcement range
                                        'Dim rx As Integer
                                        'Dim ry As Integer
                                        'Dim rw As Integer = DirectCast(mem, BattlegroupChit).effectiveReinforcement
                                        'g.DrawEllipse(Pens.Yellow, pnt.X, pnt.Y, rw * pixelspermile, rw * pixelspermile)


                                        If mem.OwningPlayer.Equals(ptrCurrentGameData.selectedPlayer) Then
                                            mem.icon.MakeTransparent(Color.FromArgb(255, 0, 255))
                                            g.DrawImage(mem.icon, pnt.X, pnt.Y, icoWidth, icoHeight)
                                        Else
                                            '//g.DrawImage(gc.Icon(cmplib01.IconImageIndex_cgd.SameFaction), pnt.X, pnt.Y, icoWidth, icoHeight)
                                            g.DrawImage(mem.icon, pnt.X, pnt.Y, icoWidth, icoHeight)
                                            '// now the supercool design that is the friend border, uhuh.
                                            '// black, yellow, black, yellow border. CHA!
                                            g.DrawRectangle(fBorderPen1, pnt.X - 1, pnt.Y - 1, CInt(icoWidth / 2), 1)
                                            g.DrawRectangle(fBorderPen2, pnt.X + CInt(icoWidth / 2) - 1, pnt.Y - 1, CInt(icoWidth / 2), 1)
                                            g.DrawRectangle(fBorderPen1, pnt.X + icoWidth - 1, pnt.Y - 1, 1, CInt(icoWidth / 2))
                                            g.DrawRectangle(fBorderPen2, pnt.X + icoWidth - 1, pnt.Y + CInt(icoWidth / 2) - 1, 1, CInt(icoWidth / 2))

                                            g.DrawRectangle(fBorderPen2, pnt.X - 1, pnt.Y - 1, 1, CInt(icoWidth / 2))
                                            g.DrawRectangle(fBorderPen1, pnt.X - 1, pnt.Y + CInt(icoWidth / 2) - 1, 1, CInt(icoWidth / 2))
                                            g.DrawRectangle(fBorderPen2, pnt.X - 1, pnt.Y + icoWidth - 1, CInt(icoWidth / 2), 1)
                                            g.DrawRectangle(fBorderPen1, pnt.X + CInt(icoWidth / 2) - 1, pnt.Y + icoWidth - 1, CInt(icoWidth / 2), 1)
                                        End If
                                    End If
                                End If
                            Catch ex As Exception
                                g.DrawImage(MyBase.picBlankImage.Image, pnt.X, pnt.Y, icoWidth, icoHeight)
                            End Try
                        Else
                            ' we need to check to see if its an enemy detected objective. :P
                            If mem.UnitType = GroundChitClass_cgd.Objective Then
                                'enemyObj = CType(GC, cmplib01.ObjectiveType)
                                If mem.detected = True Then
                                    Dim enemyPoint As Point
                                    enemyPoint = mem.Location
                                    enemyPoint.X -= (icoWidth / 2)
                                    enemyPoint.Y -= (icoHeight / 2)
                                    ' draw enemy objectives
                                    g.DrawImage(mem.icon, enemyPoint.X, enemyPoint.Y, icoWidth, icoHeight)
                                End If
                            End If
                        End If

                End Select
            Next
        Catch argEx As ArgumentOutOfRangeException

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try

        enemyBorderPen.Dispose()
        fBorderPen1.Dispose()
        fBorderPen2.Dispose()

    End Sub

    Private Sub DrawWaypoints(ByRef g As Graphics, ByVal mem As ChitMember)
        If mem.UnitType = GroundChitClass_cgd.Objective Then Exit Sub
        If ptrCurrentGameData.selectedPlayer Is Nothing Then Exit Sub

        'If GC.GroundChitClass = GroundChitClass_cgd.Objective Then Exit Sub
        'If ptrCurrentGameData.selectedPlayer Is Nothing Then Exit Sub
        If m_ReplayMode Then Exit Sub

        Dim batt As BattlegroupChit = DirectCast(mem, BattlegroupChit)

        If batt.waypoints.Count > 0 Then
            Dim waypoint As IWaypointLine
            Dim wap As New WaypointLine
            Dim selUnitWap As New SelectedUnitWaypointLine
            Dim friendlyWap As New FriendlyPlayerWaypoint
            Dim invalidWap As New InvalidWaypoint
            Dim waypointCount As Int16 = batt.waypoints.Count

            ' the selected chit is always drawn with a yellow waypoint line.
            If Not SelectedChit Is Nothing Then
                If batt Is SelectedChit Then
                    If batt.invalidWaypoint Then
                        waypoint = invalidWap
                    Else
                        waypoint = selUnitWap
                    End If

                Else
                    If batt.OwningPlayer.Equals(ptrCurrentGameData.selectedPlayer) Then
                        If batt.invalidWaypoint = True Then
                            waypoint = invalidWap
                        Else
                            waypoint = wap
                        End If
                    Else
                        waypoint = friendlyWap
                    End If
                End If
            Else
                If batt.OwningPlayer.Equals(ptrCurrentGameData.selectedPlayer) Then
                    If batt.invalidWaypoint = True Then
                        waypoint = invalidWap
                    Else
                        waypoint = wap
                    End If
                Else
                    waypoint = friendlyWap
                End If
                'If unit.OwningPlayer = ptrCurrentGameData.selectedPlayer.PlayerID Then
                '    waypoint = wap
                'Else
                '    waypoint = friendlyWap
                'End If
            End If

            ' draw the first waypoint, drawn from the unit to the first point
            waypoint.pnts.Add(batt.Location)
            waypoint.pnts.Add(batt.waypoints.item(0).LOC)

            ' draw each successive waypoint
            If waypointCount > 1 Then
                For waypointCount = 0 To waypointCount - 1
                    waypoint.pnts.Add(batt.waypoints.item(waypointCount).LOC)
                Next
            End If
            waypoint.Draw(g)
        End If

    End Sub

    Private Sub DrawBattles(ByRef g As Graphics)
        If ptrCurrentGameData.Battles_g.HT.Count = 0 Then Exit Sub
        Try
            Dim batt As Battle
            Dim key As String

            If m_BattleIconSize = BattleIconSize.Normal Then
                Dim BlastMap As New Bitmap(MyBase.picBlast.Image)

                BlastMap.MakeTransparent(Color.FromArgb(255, 0, 255))

                For Each key In ptrCurrentGameData.Battles_g.HT.Keys
                    batt = ptrCurrentGameData.Battles_g.Item(key)
                    ' if we're in the normal turn, just draw the battle, if we're in replay, draw it in the proper phase.
                    If m_ReplayMode Then
                        'TASK: replay
                        'If batt.PhaseActive <= iPhaseNumber Then
                        '    g.DrawImage(BlastMap, batt.BattleLocation.X - 16, batt.BattleLocation.Y - 16)
                        'End If
                    Else
                        g.DrawImage(BlastMap, batt.BattleLocation.X - 16, batt.BattleLocation.Y - 16)
                    End If
                Next
            ElseIf m_BattleIconSize = BattleIconSize.Small Then
                Dim BlastMap As New Bitmap(MyBase.picBlastMapSmall.Image)

                BlastMap.MakeTransparent(Color.FromArgb(255, 0, 255))

                For Each key In ptrCurrentGameData.Battles_g.HT.Keys
                    batt = ptrCurrentGameData.Battles_g.Item(key)
                    ' if we're in the normal turn, just draw the battle, if we're in replay, draw it in the proper phase.
                    If m_ReplayMode Then
                        'TASK: replay
                        'If batt.PhaseActive <= iPhaseNumber Then
                        '    g.DrawImage(BlastMap, batt.BattleLocation.X - 8, batt.BattleLocation.Y - 8)
                        'End If
                    Else
                        g.DrawImage(BlastMap, batt.BattleLocation.X - 8, batt.BattleLocation.Y - 8)
                    End If
                Next
            Else
                '// nuttin!

            End If


        Catch ex As Exception
            HandleException("FlexMapViewCampaignBuilder.DrawBattles", ex)
        End Try

    End Sub

End Class

Public Interface IWaypointLine
    Property WaypointSize() As Single
    Property WaypointColor() As Color
    Property pnts() As ArrayList
    Sub SetWaypointColor()
    Sub Draw(ByVal g As Graphics)

End Interface

Public Class WaypointLine
    Implements IWaypointLine

    ' constants
    Public Const WAYPOINTDEFAULTSIZE As Integer = 5

    ' the properties of a waypoint line :)
    Shared mPen As New Pen(Color.LightGreen)    ' so all waypoints are the same color dude.
    Friend WithEvents cdlgPick As System.Windows.Forms.ColorDialog

    ' member variables
    Private mPoints As New ArrayList(6)

    ' events
    Public Event RefreshRequest()

    Public Sub New()
        mPen.StartCap = LineCap.RoundAnchor
        mPen.EndCap = LineCap.ArrowAnchor
        mPen.Width = WAYPOINTDEFAULTSIZE
        'mPen.DashStyle = DashStyle.DashDot
        Me.cdlgPick = New System.Windows.Forms.ColorDialog()
    End Sub

    Public Property WaypointSize() As Single Implements IWaypointLine.WaypointSize
        Get
            Return mPen.Width
        End Get
        Set(ByVal Value As Single)
            mPen.Width = Value
        End Set
    End Property

    Public Sub SetWaypointColor() Implements IWaypointLine.SetWaypointColor
        Dim diagRes As New DialogResult()
        diagRes = cdlgPick.ShowDialog()

        If diagRes = DialogResult.Cancel Then Exit Sub
        mPen.Color = cdlgPick.Color
        RaiseEvent RefreshRequest()
    End Sub

    Public Property WaypointColor() As Color Implements IWaypointLine.WaypointColor
        Get
            Return mPen.Color
        End Get
        Set(ByVal Value As Color)
            mPen.Color = Value
        End Set
    End Property

    Public Overridable Sub Draw(ByVal g As Graphics) Implements IWaypointLine.Draw
        Dim pth As New GraphicsPath()
        Dim blackPen As New Pen(Color.Black)
        Dim i As Int16
        Dim thisPoint As Point
        Dim LastPoint As Point

        blackPen.StartCap = LineCap.NoAnchor
        blackPen.EndCap = LineCap.ArrowAnchor
        blackPen.Width = WAYPOINTDEFAULTSIZE + 2
        blackPen.Color = Color.Black

        For i = 1 To mPoints.Count - 1
            thisPoint = mPoints(i)
            LastPoint = mPoints(i - 1)
            pth.AddLine(LastPoint, thisPoint)
        Next

        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        g.DrawPath(blackPen, pth)
        g.DrawPath(mPen, pth)

    End Sub

    Public Property pnts() As ArrayList Implements IWaypointLine.pnts
        Get
            Return mPoints
        End Get
        Set(ByVal Value As ArrayList)
            mPoints = Value
        End Set
    End Property

End Class

Public Class SelectedUnitWaypointLine
    Inherits WaypointLine
    Private yellowPen As New Pen(Color.Yellow)

    Public Sub New()
        yellowPen.StartCap = LineCap.RoundAnchor
        yellowPen.EndCap = LineCap.ArrowAnchor
        yellowPen.Width = WAYPOINTDEFAULTSIZE
    End Sub

    Public Overrides Sub Draw(ByVal g As Graphics)
        Dim pth As New GraphicsPath()
        Dim blackPen As New Pen(Color.Black)
        Dim i As Int16
        Dim thisPoint As Point
        Dim LastPoint As Point

        blackPen.StartCap = LineCap.NoAnchor
        blackPen.EndCap = LineCap.ArrowAnchor
        blackPen.Width = WAYPOINTDEFAULTSIZE + 2
        blackPen.Color = Color.Black

        For i = 1 To MyBase.pnts.Count - 1
            thisPoint = MyBase.pnts(i)
            LastPoint = MyBase.pnts(i - 1)
            pth.AddLine(LastPoint, thisPoint)
        Next

        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        g.DrawPath(blackPen, pth)
        g.DrawPath(yellowPen, pth)

    End Sub

End Class

Public Class FriendlyPlayerWaypoint
    Inherits WaypointLine
    Private bluePen As New Pen(Color.LightGray)

    Public Sub New()
        bluePen.StartCap = LineCap.RoundAnchor
        bluePen.EndCap = LineCap.ArrowAnchor
        bluePen.Width = WAYPOINTDEFAULTSIZE
    End Sub

    Public Overrides Sub Draw(ByVal g As Graphics)
        Dim pth As New GraphicsPath()
        Dim blackPen As New Pen(Color.Black)
        Dim i As Int16
        Dim thisPoint As Point
        Dim LastPoint As Point

        blackPen.StartCap = LineCap.NoAnchor
        blackPen.EndCap = LineCap.ArrowAnchor
        blackPen.Width = WAYPOINTDEFAULTSIZE + 2
        blackPen.Color = Color.Black

        For i = 1 To MyBase.pnts.Count - 1
            thisPoint = MyBase.pnts(i)
            LastPoint = MyBase.pnts(i - 1)
            pth.AddLine(LastPoint, thisPoint)
        Next

        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        g.DrawPath(blackPen, pth)
        g.DrawPath(bluePen, pth)

    End Sub

End Class

Public Class InvalidWaypoint
    Inherits WaypointLine
    Private bluePen As New Pen(Color.Crimson)

    Public Sub New()
        bluePen.StartCap = LineCap.RoundAnchor
        bluePen.EndCap = LineCap.ArrowAnchor
        bluePen.Width = WAYPOINTDEFAULTSIZE
    End Sub

    Public Overrides Sub Draw(ByVal g As Graphics)
        Dim pth As New GraphicsPath()
        Dim i As Int16
        Dim thisPoint As Point
        Dim LastPoint As Point
        Dim blackPen As New Pen(Color.Black)

        blackPen.StartCap = LineCap.NoAnchor
        blackPen.EndCap = LineCap.ArrowAnchor
        blackPen.Width = WAYPOINTDEFAULTSIZE + 2
        blackPen.Color = Color.Black

        For i = 1 To MyBase.pnts.Count - 1
            thisPoint = MyBase.pnts(i)
            LastPoint = MyBase.pnts(i - 1)
            pth.AddLine(LastPoint, thisPoint)
        Next

        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        g.DrawPath(blackPen, pth)
        g.DrawPath(bluePen, pth)
    End Sub

End Class


